from utils.model import JobLibModel
from prettytable import PrettyTable
from utils import *
import os
from time import time
from sklearn.svm import SVC
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
import numpy as np
import joblib
from colorama import Back, Style, Fore

import torch 
from torch import nn
from torch import optim


def init(meta_data_file="./data/meta.json", n_path="./data/negative", p_path="./data/positive"):
    """
        initialise for the project
    """
    print(Back.BLUE, "INIT", Style.RESET_ALL, Fore.BLUE, "Check Path and Create Meta", Style.RESET_ALL)
    if not os.path.exists("./data"):
        raise FileExistsError("folder ./data doesn't exist!")
    if not os.path.exists("./data/negative"):
        raise FileExistsError("folder ./data/negative doesn't exist!")
    if not os.path.exists("./data/positive"):
        raise FileExistsError("folder ./data/positive doesn't exist!")
    
    get_meta_data(
        meta_data_file=meta_data_file,
        n_path=n_path,
        p_path=p_path
    )
    if not os.path.exists("./model"):
        os.mkdir("./model")
    print(Back.GREEN, "DONE", Style.RESET_ALL, Fore.GREEN, "initial successfully", Style.RESET_ALL)

    train_x, train_y = load_abnormal(return_numpy=True, train=True, X_type="mfcc_vector")
    test_x, test_y = load_abnormal(return_numpy=True, train=False, X_type="mfcc_vector")
    return train_x, train_y, test_x, test_y

def row_from_train(model_name : str, model_class : type, parameters : dict, train_x : np.ndarray, 
                    train_y : np.ndarray, test_x : np.ndarray, test_y : np.ndarray, model_path : str) -> list:
    print(Back.BLUE, "TRAIN", Style.RESET_ALL, Fore.BLUE, "training {}".format(model_name), Style.RESET_ALL)
    row = [model_name]
    model : JobLibModel = model_class(**parameters)
    s1 = time()
    model.fit(train_x, train_y)
    s2 = time()
    acc = model.score(test_x, test_y)
    s3 = time()
    model.save_model(model_path)
    row.extend([str(s2 - s1), str(s3 - s2), str(acc)])
    return row



if __name__ == "__main__":
    train_x, train_y = load_abnormal(return_numpy=True, train=True, meta_path="./data/meta_0db_id_00.json", p_flag="normal", n_flag="abnormal")
    test_x, test_y = load_abnormal(return_numpy=True, train=False, meta_path="./data/meta_0db_id_00.json", p_flag="normal", n_flag="abnormal")
    
    row_from_train(
        model_name="Bagging based on SVM", model_class=ASBaggingSVM,
        parameters={"base_estimator" : SVC(C=100), "n_estimators" : 200, "max_samples" : 0.8},
        train_x=train_x, train_y=train_y,
        test_x=test_x, test_y=test_y,
        model_path="./model/bagging_svc.joblib"
    )
